import { Vec3 } from 'cc';
import { BilliardGame } from '../game/BilliardGame';
import { EventManager } from '../core/EventManager';
import { HitPath } from '../ai/aicore';
import { TableAtrribute } from '../core/TableAttribute';

enum SimulateStage {
  InitDefault = 0,       // 初始状态
  AimTargetPosition = 1, // 瞄准目标
  AdjustDirection = 2,   // 调整方向
  AdjustForce = 3,       // 调整力度
  Finished = 4,          // 结束
}

export class HumanAiSimulation {
  private stage = 0;
  private timestamp = 0;
  private radius = 0.5;
  private aimTime = 20;
  private directionTime = 35;
  private forceTime = 20;
  public startSimulation() {
    this.timestamp = 0;
    this.stage = SimulateStage.AimTargetPosition;

    this.aimTime = Math.ceil(Math.random() * 60) + 30;
    this.directionTime = Math.ceil(Math.random() * 200) + 10;
    this.forceTime = Math.ceil(Math.random() * 100) + 50;
  }
  public simulateHuman(bestPath: HitPath) {
    this.timestamp += 1;
    // 1. 选择击打 目标球/目标位置
    if (this.stage === SimulateStage.AimTargetPosition) {
      if (this.timestamp >= this.aimTime) {
        // 1.1 选择目标球/目标位置
        if (bestPath.hasDirectHitBall() && bestPath.targetBall) { 
          const v = new Vec3(bestPath.targetBall.position.x, TableAtrribute.DeskTopAxisY, bestPath.targetBall.position.y);
          EventManager.Instance().Emit("HitBallHasChoosed", v);
        } else {
          const v = new Vec3(bestPath.targetPos.x, TableAtrribute.DeskTopAxisY, bestPath.targetPos.y);
          EventManager.Instance().Emit("HitBallHasChoosed", v);
        }
        this.stage = SimulateStage.AdjustDirection; this.timestamp = 0;
      }
    }
    if (this.stage === SimulateStage.AdjustDirection) {
      if (this.timestamp < this.directionTime) { // 2.1 调整方向
        if (this.timestamp % 11 === 0 && bestPath.hasDirectHitBall() && bestPath.targetBall) {
          const w = this.timestamp / (this.directionTime + 1);
          const nw = (1 - w);
          const v = new Vec3(
            w * bestPath.targetPos.x + nw * bestPath.targetBall.position.x,
            TableAtrribute.DeskTopAxisY,
            w * bestPath.targetPos.y + nw * bestPath.targetBall.position.y,
          );
          EventManager.Instance().Emit("HitBallHasChoosed", v);
        }
      } else if (this.timestamp === this.directionTime + 1) { // 2.2 直接设置到球洞目标
        var v = new Vec3(bestPath.targetPos.x, TableAtrribute.DeskTopAxisY, bestPath.targetPos.y);
        EventManager.Instance().Emit("HitBallHasChoosed", v);
      } else if (this.timestamp > this.directionTime + 15) { // 2.3 扭转到下一步
        this.stage = SimulateStage.AdjustForce; this.timestamp = 0;
        if (Math.abs(bestPath.spin.y) > 0.1 ) {
          const spin = new Vec3(0, bestPath.spin.y, 0);
          BilliardGame.Instance().hasSpinHitBall = true;
          EventManager.Instance().Emit("ChangeOffsetSpinPosition", spin);
        }
      }
    }
    // 3. 调整力度
    if (this.stage === SimulateStage.AdjustForce) {
      const range = 0.25 * bestPath.maxForce + bestPath.force;
      const force = Math.min(1.0, range);
      if (this.timestamp >= this.forceTime) {
        EventManager.Instance().Emit("QiuGanForceEnded", force);
        BilliardGame.Instance().actionStage.forceFinished();
        this.stage = SimulateStage.Finished;  this.timestamp = 0;
      } else {
        if (this.timestamp > 20 && this.timestamp % 10 === 9) {
          const per = this.timestamp / (this.forceTime + 1);
          EventManager.Instance().Emit("QiuGanForceChanged", per * force);
        }
      }
    }
  }
  public isEndAimDirection() {
    return (this.stage === SimulateStage.AdjustDirection && this.timestamp === 10);
  }
}

